package com.course.web.component.base;

import com.vaadin.data.BeanValidationBinder;
import com.vaadin.data.Binder;
import com.vaadin.ui.*;

/**
 * Created by Justin on 2017/5/24.
 */
public class BaseEdit<T> extends Window {

    private final Binder<T> binder;
    private final Button save;
    private final Button back;
    private final Layout bars;

    private Handler<T> handler;

    public BaseEdit(Class<T> type, String save, String back, String caption, Handler<T> handler) {
        this.binder = new BeanValidationBinder<>(type);
        this.save = new Button(save);
        this.back = new Button(back);
        this.bars = new HorizontalLayout();
        this.handler = handler;
        this.binder.addStatusChangeListener(event -> this.save.setEnabled(this.binder.isValid()));
        this.save.addClickListener(event -> save());
        this.back.addClickListener(event -> back());
        setCaption(caption);
        setModal(true);
    }

    public BaseEdit(Class<T> type, String save, String back, String caption) {
        this(type, save, back, caption, null);
    }

    public BaseEdit(Class<T> type, String save, String back) {
        this(type, save, back, null);
    }

    public BaseEdit(Class<T> type) {
        this(type, "确定", "取消");
    }

    public BaseEdit initEdit(Component edit) {
        VerticalLayout root = new VerticalLayout();
        if (edit != null) {
            edit.setWidthUndefined();
            root.addComponent(edit);
        }
        root.addComponent(bars);
        bars.addComponent(save);
        bars.addComponent(back);
        setContent(root);
        center();
        return this;
    }

    public void setHandler(Handler<T> handler) {
        this.handler = handler;
    }

    public Binder<T> binder() {
        return binder;
    }

    public void show(UI ui, T bean) {
        if (bean != null) {
            binder.setBean(bean);
            ui.addWindow(this);
        }
    }

    public Layout getBars() {
        return bars;
    }

    private void save() {
        if (handler != null && binder.getBean() != null) {
            handler.onSave(binder.getBean());
        }
        close();
    }

    private void back() {
        close();
    }

    @FunctionalInterface
    public interface Handler<T> {
        void onSave(T bean);
    }
}
